﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpTRI
{
    abstract class Character
    {
        public Character() :this(0,0,0)
        {

        }
        public Character(float x, float y, float z)
        {
            Attributes = new StatusAttributes();
            Mesh = Xors3D.xCreateSphere();
            Xors3D.xPositionEntity(Mesh, x, y, z);
            Destination = Position;
            lastKick = DateTime.Now.Millisecond;
        }
        public Character(Vec3D position) :this(position.X, position.Y, position.Z)
        {

        }

        public void Attack(Character target)
        {
            MoveToPoint(target.Position);
            mTarget = target;
        }

        public void SetDirection(Vec3D dir)
        {
            float pitch = Xors3D.xVectorPitch(dir.X, dir.Y, dir.Z);
            float yaw = Xors3D.xVectorYaw(dir.X, dir.Y, dir.Z);
            float roll = 0;
            Xors3D.xRotateEntity(Mesh, pitch, yaw, roll, true);
        }


        public Character SelectedEnemy(List<Character> enemies)
        {
            foreach (var enemy in enemies)
            {
                if (DistanceTo(enemy.Position) < 3)
                {
                    return enemy;
                }
            }
            return null;
        }

        public Vec3D Position
        {
            get
            {
                return new Vec3D(Xors3D.xEntityX(Mesh, true),Xors3D.xEntityY(Mesh, true), Xors3D.xEntityZ(Mesh, true));
            }
        }

        public void MoveToPoint(Vec3D destination)
        {
            SetDirection(new Vec3D(Position, destination));
            Destination = destination;
            if (mTarget != null)
            {
                mTarget.Attacked = false;            
            }
            mTarget = null;
        }

        public void Move()
        {
            if (!InPosition(Destination))
            {
                Xors3D.xMoveEntity(Mesh, 0, 0, (float)Attributes.MoveSpeed * .1f);
            }
        }

        public float DistanceTo(Vec3D point)
        {
            return (new Vec3D(Position, point)).Lenght();
        }

        public bool InPosition(Vec3D position)
        {
            return DistanceTo(position) < .5f ? true : false;
        }

        public void DealDamage(Character target)
        {
            if (!target.IsDead())
            {
                int currentTime = DateTime.Now.Millisecond;
                if (currentTime - lastKick > Attributes.AttackSpeed)
                {
                    target.Attributes.TakeDamage(Attributes.Strength + Attributes.Damage);
                    lastKick = DateTime.Now.Millisecond;
                }
                target.mTarget = this;
                target.Attacked = true;
            }
            else
            {
                target.mTarget = null;
                target.Attacked = false;
                mTarget = null;                
            }
        }

        public bool IsDead()
        {
            return Attributes.Health == 0;
        }

        public abstract void Update();

        public bool Attacked { get; set; }
        public int Mesh { get; protected set; }
        public StatusAttributes Attributes { get; protected set; }
        public Vec3D Destination { get; set; }
        protected Character mTarget;
        protected int lastKick;
    }
}
